/**
  学习控制流
  条件  if
  循环  for,loop,while
       注意:for有各种各样的实现方式
*/
use std::io;
#[allow(unused_assignments)]
fn main() {
    println!("请输入你的年龄");
    let mut age:String = String::new();
    io::stdin().read_line(&mut age).expect("读取失败");
    let age: u32 = age.trim().parse().expect("请输入一个数字");

    let mut desc = String::new();
    let mut total: u32 = 0;

    //1.0 测试 if ,else if
    if age < 20 {
        println!("你是{}岁,还年轻", age);
        total = cal_young(age);
    } else if age < 70 {
        println!("你是{}岁,正当壮年，是国家和家庭栋梁", age);
        total = cal_strong(age);
    } else {
        println!("你是{}岁！老骥伏枥，志在千里；壮士暮年，烈心不已", age);
        total = cal_old(age);
    }

    //1.1 测试if 条件表达式赋值
    //rust的函数和许多语句中，如果最后一个语句不带分号，往往表示返回值

    desc = if age < 70 {
        "壮年".to_string()
    } else {
        "老年".to_string()
    };
    println!("{}岁，属于{}", age, desc);

    println!("总数={}", total);

    //for 循环比较多实现方式
    // a. in [] array  ,例如  in [1,2,3]
    // b. in range   ,例如  in (1..10),但10不在内
    if age <= 50 {
        let fib: u32 = cal_fb(age);
        println!("{}的斐波那契值={}", age, fib);
    }

    test_for_with_array();
    test_for_with_tuple();
}

//for循环-数组
fn test_for_with_array() {
    println!("for遍历数组");
    for i in [1, 2, 3, 10] {
        println!("数组元素:{}", i);
    }
}

//for循环-元组,..
//使用..的时候，两边带不带()都是一样的。带()主要是为了构建一个对象，便于左其它操作
fn test_for_with_tuple() {
    for i in 1..5 {
        println!("{}", i);
    }
    for i in 6..10 {
        println!("{}", i);
    }
    //倒数
    //
    for i in (1..10).rev() {
        println!("倒数：{}", i);
    }
}

fn cal_young(a: u32) -> u32 {
    let mut total: u32 = 0;
    //测试for循环
    //注意 写成 n..m 那么上限是不会计算在内的
    for i in 1..a + 1 {
        total += i;
    }
    return total;
}

fn cal_strong(a: u32) -> u32 {
    let mut i = 0;
    let mut total: u32 = 0;
    //测试loop,必须内部加break;
    loop {
        i = i + 1;
        total = total + i;
        if i == a {
            break;
        }
    }
    return total;
}

fn cal_old(a: u32) -> u32 {
    let mut total: u32 = 0;
    let mut i = 0;
    //测试while
    while i < a {
        i = i + 1;
        total = total + i;
    }
    return total;
}
/**
 计算斐波那契，但是这个不要用于计算太大的值，因为这个递归算法极其低效
 计算50以内还马马虎虎
 注意:如果有错误，那么非蛇形的命名方式会被编译器提示出来
*/
fn cal_fb(n: u32) -> u32 {
    if n == 1 {
        return 1;
    } else if n == 2 {
        return 1;
    } else {
        return cal_fb(n - 1) + cal_fb(n - 2);
    }
}
